package com.crazymaker.springcloud.demo.security;

import com.crazymaker.springcloud.common.constants.SessionConstants;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.util.matcher.RequestHeaderRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class DemoAuthFilter extends OncePerRequestFilter {

    private AuthFailureHandler failureHandler = new AuthFailureHandler();

    private AuthenticationManager authenticationManager;

    private static final String AUTHORIZATION_HEAD = "token";

    private RequestMatcher matcher = new RequestHeaderRequestMatcher(AUTHORIZATION_HEAD);

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        AuthenticationException failed = null;


        try {
            if (!matcher.matches(request)) {
                filterChain.doFilter(request, response);
                return;
            }
            String headToken = request.getHeader(SessionConstants.AUTHORIZATION_HEAD);
            String[] split = headToken.split(",");
//            DemoToken demoToken = new DemoToken(split[0], split[1]);
            UsernamePasswordAuthenticationToken demoToken = new UsernamePasswordAuthenticationToken(split[0], split[1]);

            // 返回的是Authentication对象
            Authentication resultToken = authenticationManager.authenticate(demoToken);
            if (resultToken.isAuthenticated()) {
                // 验证通过
                SecurityContextHolder.getContext().setAuthentication(resultToken);
                filterChain.doFilter(request, response);
                return;
            }
        } catch (Exception e) {
            logger.error("认证有误", e);
            failed = new AuthenticationServiceException("请求头认证消息格式错误", e);
        }
        if (failed == null) {
            failed = new AuthenticationServiceException("认证失败");
        }
        SecurityContextHolder.clearContext();
        failureHandler.onAuthenticationFailure(request, response, failed);
    }

    public AuthenticationManager getAuthenticationManager() {
        return authenticationManager;
    }

    public void setAuthenticationManager(AuthenticationManager authenticationManager) {
        this.authenticationManager = authenticationManager;
    }
}
